package com.szwistar.common.datastruct;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class JsonMapper {
	static final ObjectMapper jsonMapper = new ObjectMapper();
	public static ObjectMapper getMapper() { return jsonMapper; }

	static {
		// 设置属性: 遇到不可识别的属性时，继续编码
		getMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
		// 设置属性: 遇到不可识别的属性时，继续解析
		getMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
	}

	public static String toJson(Object obj) throws Exception {
		if(obj instanceof JsonableType) { return ((JsonableType) obj).toJson(); }
		return getMapper().writeValueAsString(obj);
	}

	public static <T> T fromJson(String json, Class<? extends T> typeClass) throws Exception {
		if((json == null) || json.isEmpty() || (typeClass ==null)) { return null; }
		return getMapper().readValue(json, typeClass);
	}

	public static <T> T[] fromJsonAsArrayOf(String json, Class<? extends T> typeClass) throws Exception {
		if((json == null) || json.isEmpty() || (typeClass ==null)) { return null; }
		JavaType type = getMapper().getTypeFactory().constructArrayType(typeClass);
		return getMapper().readValue(json, type);
	}

	public static <T> ArrayList<T> fromJsonAsListOf(String json, Class<? extends T> typeClass) throws Exception {
		if((json == null) || json.isEmpty() || (typeClass ==null)) { return null; }
		JavaType type = getMapper().getTypeFactory().constructCollectionType(ArrayList.class, typeClass);
		return getMapper().readValue(json, type);
	}

	public static <K,T> Map<K,T> fromJsonAsMapOf(String json, Class<? extends K> keyClass, Class<? extends T> valueClass) throws Exception {
		return fromJsonAsMapOf(json, HashMap.class, keyClass, valueClass);
	}

	@SuppressWarnings("rawtypes")
	public static <K,T> Map<K,T> fromJsonAsMapOf(String json, Class<? extends Map> mapClass, Class<? extends K> keyClass, Class<? extends T> valueClass) throws Exception {
		if((json == null) || json.isEmpty() || (keyClass ==null) || (valueClass ==null)) { return null; }
		JavaType type = getMapper().getTypeFactory().constructMapType(mapClass, keyClass, valueClass);
		return getMapper().readValue(json, type);
	}

	/**
	 * 默认情况下，转化为Map<String, Object>
	 */
	public static JsonObject fromJson(String json) throws Exception {
		if(Utils.isEmpty(json)) { return null; }
        //JavaType type = JsonMapper.getMapper().getTypeFactory().constructMapType(HashMap.class, String.class, Object.class);
        //return JsonMapper.getMapper().readValue(json, type);
		JsonObject ret = fromJson(json, JsonObject.class);
		return ret;
	}

	public static void main(String argv[]) throws Exception {
		String json = "{\"name\": \"zy\", \"work\": {\"year\": 123, \"job\": \"soft\"}}";
		Map<String, Object> obj = fromJson(json);
		json = toJson(obj);
		System.out.println(json);

		Object obj2 = fromJson(json, Object.class);
		json = toJson(obj2);
		System.out.println(json);
	}
}
